/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gui.treeQuery;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
//import java.util.Map.Entry;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

/**
 *
 * @author jorgeorm
 */
public class NodeSelectionListener extends MouseAdapter{
    private JTree tree;
    private HashMap<CheckBoxNode, Boolean> grupoMap;
    private ArrayList<CheckBoxNode> listaDims;
    
    public NodeSelectionListener(JTree tree) {
        this.tree=tree;
        grupoMap= new HashMap<CheckBoxNode, Boolean>();
        listaDims= new ArrayList<CheckBoxNode>();
    }
    
    public NodeSelectionListener(JTree tree, HashMap <CheckBoxNode, Boolean>map) {
        this.tree=tree;
        grupoMap= map;
        listaDims= new ArrayList<CheckBoxNode>();
//        System.out.println("Log GrupoMap: "+grupoMap);
    }
    
    public ArrayList<CheckBoxNode> getSeleccionDims()
    {
        return this.listaDims;
    }
    
    public CheckBoxNode nodoHechoSeleccionado()
    {
        CheckBoxNode nodoSeleccionado=null;
        if(grupoMap.containsValue(true)){
            Iterator<Map.Entry<CheckBoxNode, Boolean>> it = grupoMap.entrySet().iterator();
            while( it.hasNext()) {
                Map.Entry<CheckBoxNode, Boolean> tuplaGrupo = it.next();
                if(tuplaGrupo.getValue()) nodoSeleccionado=tuplaGrupo.getKey();
            }
        }
        return nodoSeleccionado;
    }
    
    @Override
    public void mouseClicked(MouseEvent evnt)
    {
        int x= evnt.getX();
        int y= evnt.getY();
        int row=tree.getRowForLocation(x, y);
        TreePath path= tree.getPathForRow(row);
        
        if(path!=null)
        {
            CheckBoxNode node= (CheckBoxNode)path.getLastPathComponent();
//            System.out.println("Log del Nodo, tieneGrupo?: "+node.hasGroup());
//            System.out.println("Log del Nodo, valor en grupo?: "+grupoMap.get(node));
            boolean isSelected = !(node.isSelected());
            if(node.hasGroup()){
                cambioGrupo(node);
            }else {//Es una dimensión
                if(node.isLeaf()&&isSelected){
                    listaDims.add(node);
                }else if(node.isLeaf()){
                    listaDims.remove(node);
                }
                node.setSelected(isSelected);
                ((DefaultTreeModel) tree.getModel()).nodeChanged(node);
            }
            tree.repaint();
            if(row==0)
            {
                tree.revalidate();
                tree.repaint();
            }
        }
    }
    
//    cambia la selección de los checkBox que están en el grupo. y pone el nuevo valor del checkbox nodoAcambiar
//    
    private void cambioGrupo(CheckBoxNode nodeHechoNuev)
    {
//        System.out.println("Entro al cambio de grupo");
        CheckBoxNode nodeHechoPrev=null;
//        Si existe uno en el grupo con True
//        
        if(grupoMap.containsValue(true)){        
//            System.out.println("Hay uno con true");

//            Recorre el grupo buscando al true para setearlo en false y si no es de la misma estrella que el nodo a cambiar el valor
//            
            for (Iterator it = this.grupoMap.entrySet().iterator(); it.hasNext();) {
                Map.Entry<CheckBoxNode,Boolean> object = (Map.Entry<CheckBoxNode,Boolean>) it.next();//Saca una entrada del HashMap
                if(object.getValue()){//Dependiendo de si es la que tiene el true entra
//                    System.out.println("Encontré el True en: "+object.getKey().toString());
                    nodeHechoPrev=(CheckBoxNode)object.getKey();//saca el nodo de este valor en el grupo
//                    CheckBoxNode papa= (CheckBoxNode)nodeHechoPrev.getParent();//Saca al papá del nodo
                    boolean hermanos=nodeHechoPrev.isNodeSibling(nodeHechoNuev);
//                    System.out.println("Nodos son hermanos?: "+hermanos);
                    if(!hermanos) {//Viejo y nuevo selecto no son hermanos
//                        System.out.println("La list acontiene: "+listaDims.toString());
                        while(!(listaDims.isEmpty())) {  
                            CheckBoxNode nodoAtribDim = listaDims.remove(0);
                            nodoAtribDim.setSelected(false);
//                            ((DefaultTreeModel) tree.getModel()).nodeChanged(nodoAtribDim);
                        }
//                        ((DefaultTreeModel) tree.getModel()).nodeChanged(papa);
//                        tree.repaint();
                    }//Si no son hermanos pone selección a todos los hijos del padre
                    nodeHechoPrev.setSelected(false);
                    grupoMap.put(nodeHechoPrev, nodeHechoPrev.isSelected());
                }
            }
        }
        grupoMap.put(nodeHechoNuev, Boolean.TRUE);
        nodeHechoNuev.setSelected(true);
    }
    
    private void dbg(Object ...obj)
    {
        System.out.println(Arrays.deepToString(obj));
    }
    
    public boolean isInGrupo(CheckBoxNode nodo)
    {
        boolean salida=false;
        Boolean val= null;
        val=grupoMap.get(nodo);
        if(val!=null)
        {
            salida=true;
        }
        return salida;    
    }
    
}
